package utils

import (
	"fmt"
	"os"
	"sync"
	"sync/atomic"
	"time"
)

// 信号组
type MultiGroupTaskSignGroup struct {
	groupid interface{}
	list    sync.Map

	dispflag    int32
	lastdisp_t  time.Time
	lastdispstr string
}

func (this *MultiGroupTaskSignGroup) Add(signRec *MultiGroupTaskSignRec) bool {
	if _, loaded := this.list.LoadOrStore(signRec.id, signRec); loaded {
		return false
	}
	return true
}

func (this *MultiGroupTaskSignGroup) Remove(signid interface{}) {
	this.list.Delete(signid)
}

func (this *MultiGroupTaskSignGroup) Count() int {
	i := 0
	this.list.Range(func(key, value interface{}) bool {
		i++
		return true
	})
	return i
}

func (this *MultiGroupTaskSignGroup) Execute(sender *MultiGroupTaskRec) int {
	if atomic.CompareAndSwapInt32(&this.dispflag, 0, 1) {
		defer func() { this.dispflag = 0 }()
		this.lastdisp_t = time.Now()
		rval := 0
		this.lastdispstr = fmt.Sprintf("[%s] goid:%d, groupid:%v\r\n", NowString(), GetCurrentGoRoutineID(), this.groupid)
		this.list.Range(func(key, value interface{}) bool {
			rec := value.(*MultiGroupTaskSignRec)
			this.lastdispstr += fmt.Sprintf("  ->[%s]key:%v\r\n", NowString(), rec.id)
			rec.cb(sender.Args...)
			rval++
			return true
		})
		return rval
	} else {
		if time.Now().Sub(this.lastdisp_t).Seconds() > 10 {
			fmt.Fprintf(os.Stderr, "[%s][警告]信号组[%v]逻辑执行堵塞, lastdispinfo:%s\r\n", NowString(), this.groupid, this.lastdispstr)
		}
		return -1
	}
}
